package net.chrisrichardson.ec2deployer.cluster

import net.chrisrichardson.ec2deployer.core.EC2Server
import net.chrisrichardson.ec2deployer.core.AWSProperties
import net.chrisrichardson.ec2deployer.core.EC2
import groovy.mock.interceptor.MockFor
import net.chrisrichardson.ec2deployer.applications.*

class WebServerTierTest extends GroovyTestCase {

    def awsProperties
    def mockAppServerTier
    def mockApacheServer
    def apacheInstance
    def mockEc2Server
    def mockEc2
    ClusterSpec clusterSpec

    public void setUp() {
        def props = new Properties()
        awsProperties = new AWSProperties(props)
        mockAppServerTier = new MockFor(AppServerTier.class)
        mockApacheServer = new MockFor(ApacheServer)
        mockEc2Server = new MockFor(EC2Server)
        mockEc2 = new MockFor(EC2.class)
        clusterSpec = new ClusterSpec()

    }

    public void testAssignHosts() {
        def apacheInstance = new EC2Server()
        def hosts = new ClusterHosts(apacheServer: apacheInstance)

        def ec2 = new EC2(awsProperties)

        def tomcats = [new TomcatServer()]

        mockAppServerTier.demand.getTomcats {tomcats}

        mockAppServerTier.use {

            def webServerTier = new WebServerTier(ec2, null, new AppServerTier())
            webServerTier.assignHosts(hosts)

            assertEquals apacheInstance, webServerTier.apacheServer.host
            assertEquals tomcats, webServerTier.apacheServer.tomcats
        }

    }

    public void testStart() {

        def ec2 = new EC2(awsProperties)

        def tomcats = [new TomcatServer()]

        mockApacheServer.demand.configure {}

        mockApacheServer.use {
            mockAppServerTier.use {
                def apacheInstance = new EC2Server()
                def hosts = new ClusterHosts(apacheServer: apacheInstance)

                def webServerTier = new WebServerTier(ec2, clusterSpec, new AppServerTier())
                webServerTier.assignHosts(hosts)

                webServerTier.start()

            }
        }

    }

    public void testSaveState() {

        def ec2 = new EC2(awsProperties)

        def tomcats = [new TomcatServer()]

        mockApacheServer.demand.getHost {apacheInstance}
        mockEc2Server.demand.getInstanceId {"i-apache"}


        mockEc2Server.use {
            mockApacheServer.use {
                mockAppServerTier.use {
                    apacheInstance = new EC2Server()
                    def hosts = new ClusterHosts(apacheServer: apacheInstance)

                    def webServerTier = new WebServerTier(ec2, null, new AppServerTier())
                    webServerTier.assignHosts(hosts)

                    def state = [:]
                    webServerTier.saveState(state)
                    assertEquals([apacheServer: ["i-apache"]], state)

                }
            }
        }

    }

    public void testRestoreState() {

        def tomcats = [new TomcatServer()]
        def apacheInstance = new EC2Server()

        mockAppServerTier.demand.getTomcats {tomcats}
        mockEc2.demand.findInstance {id -> apacheInstance}

        mockEc2.use {
            mockAppServerTier.use {
                def ec2 = new EC2(awsProperties)
                def hosts = new ClusterHosts(apacheServer: apacheInstance)

                def webServerTier = new WebServerTier(ec2, null, new AppServerTier())

                webServerTier.restoreState([apacheServer: ["i-apache"]])

                assertEquals apacheInstance, webServerTier.apacheServer.host
                assertEquals tomcats, webServerTier.apacheServer.tomcats
            }
        }

    }

    public void testStartWithExternalIp() {


        def tomcats = [new TomcatServer()]

        clusterSpec.externalIpAddress("1.2.3.4")


        mockEc2.use {
            def ec2 = new EC2(awsProperties)
            def theEc2Server = new EC2Server(ec2, "i-124", "ami-4545", "running", "oakland")

            mockApacheServer.demand.configure {}
            mockApacheServer.demand.getHost { theEc2Server }

            mockEc2.demand.associateAddress { ec2Server, ipAddress ->
                assertEquals theEc2Server, ec2Server
                assertEquals  "1.2.3.4", ipAddress
            }
            mockApacheServer.use {
                mockAppServerTier.use {
                    def apacheInstance = new EC2Server()
                    def hosts = new ClusterHosts(apacheServer: apacheInstance)

                    def webServerTier = new WebServerTier(ec2, clusterSpec, new AppServerTier())
                    webServerTier.assignHosts(hosts)

                    webServerTier.start()

                    webServerTier.assignIpAddress()

                }
            }
        }

    }


}